#include-once

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <File.au3>
#include <Constants.au3>
#include <Misc.au3>

#include "graphic.au3"
#include "metrocontrol.au3"
#include "common.au3"

Func _Tiles_Init(ByRef $hGUI, $iX, $iY, $iMax)
	Global $aTiles[$iMax][9]
	Global $hParent = $hGUI
	Local $aReturn[3] = [$hGUI, $iX, $iY]
	Return $aReturn
EndFunc   ;==>_Tiles_Init

Func _Tiles_AddTile(ByRef $aData, $iID, $iX, $iY, $iWidth, $sImage, $sLink, $sText = "")
	Local $hTile = GUICreate("Tile", $iWidthUnit * $iWidth + $iSpace * ($iWidth - 1), $iWidthUnit, $aData[1] + $iX * $iWidthUnit + $iX * $iSpace, $aData[2] + $iY * $iWidthUnit + $iY * $iSpace, $WS_CHILD, $WS_EX_MDICHILD, $aData[0])
	WinMove($hTile, "", $aData[1] + $iX * $iWidthUnit + $iX * $iSpace, $aData[2] + $iY * $iWidthUnit + $iY * $iSpace, $iWidthUnit * $iWidth + $iSpace * ($iWidth - 1), $iWidthUnit)
	$aTiles[$iID][0] = $hTile ;Handle
	$aTiles[$iID][1] = $sLink ;Link
	$aTiles[$iID][2] = $sImage ;Picture or background
	$aTiles[$iID][3] = $sText ;Text
	$aTiles[$iID][4] = $iWidth ;Width
	$aTiles[$iID][5] = 0 ;Picture control ID (if present)
	$aTiles[$iID][6] = $iX ;Tile X
	$aTiles[$iID][7] = $iY ;Tile Y
	$aTiles[$iID][8] = 0 ;Text control ID
	If FileExists($sImage) Then
		If $iWidth = 1 Then
			Local $hImg = GUICtrlCreatePic("", 0, 0, $iWidthUnit, $iWidthUnit)
			$aTiles[$iID][5] = $hImg
			GUICtrlSetState(-1, $GUI_DISABLE)
			GUICtrlSetResizing(-1, $GUI_DOCKBORDERS)
			Local $hImage = _GDIPlus_ScaleImage($sImage, $iWidthUnit, $iWidthUnit)
			Local $hBmp = _GDIPlus_BitmapCreateDIBFromBitmap($hImage)
			_WinAPI_DeleteObject(GUICtrlSendMsg($hImg, 0x0172, 0, $hBmp))
		EndIf
	ElseIf StringLeft(Binary($sImage), 2) = "0x" Then
		If Binary($sImage) = "0x000001" Then
			GUISetBkColor(0x000000, $hTile)
		EndIf
		GUISetBkColor($sImage, $hTile)
	Else
		GUISetBkColor(0x000000, $hTile)
	EndIf
	If FileExists($sLink) And StringRight($sLink, 3) = "exe" Then
		GUICtrlCreateIcon($sLink, 0, 4, 4, 32, 32)
		GUICtrlSetResizing(-1, $GUI_DOCKALL)
	EndIf
	Local $hLabel = _MetroUI_CreateLabel($hTile, $sText, $iWidthUnit / 9, $iWidthUnit / 9 * 7, $iWidthUnit * $iWidth + $iSpace, 32, 14, 0x000000)
	$aTiles[$iID][8] = $hLabel
	GUICtrlSetResizing(-1, $GUI_DOCKLEFT)
	GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "_Tiles_Drag")
	GUISetOnEvent($GUI_EVENT_SECONDARYDOWN, "_Tiles_RClick")
	GUISetState(@SW_SHOW)
	GUISwitch($aData[0])
	Return $hTile
EndFunc   ;==>_Tiles_AddTile

Func _Tiles_TileGetPos($hTile)
	Local $aFirstWinPos = WinGetPos($aTiles[0][0])
	Local $iAddX = $iTilesZoneX - $aFirstWinPos[0]
	Local $iAddY = $iTilesZoneY - $aFirstWinPos[1]
	For $i = 0 To UBound($aTiles) - 1 Step 1
		If $aTiles[$i][0] = $hTile Then
			Local $aWinPos = WinGetPos($aTiles[$i][0])
			Local $iX = $aWinPos[0] + $iAddX
			Local $iY = $aWinPos[1] + $iAddY
			If $iX > $iWidthUnit Then
				Do
					$iX -= $iSpace
				Until IsInt($iX / $iWidthUnit)
				$iX = $iX / $iWidthUnit - 1
			Else
				$iX = 0
			EndIf
			If $iY > $iWidthUnit Then
				Do
					$iY -= $iSpace
				Until IsInt($iY / $iWidthUnit)
				$iY = $iY / $iWidthUnit - 1
			Else
				$iY = 0
			EndIf
			Local $aRet[2] = [$iX, $iY]
			Return $aRet
		EndIf
	Next
EndFunc   ;==>_Tiles_TileGetPos

Func _Tiles_TileGetID($hTile)
	For $i = 0 To UBound($aTiles) - 1 Step 1
		If $hTile = $aTiles[$i][0] Then
			Return $i
		EndIf
	Next
EndFunc   ;==>_Tiles_TileGetID

Func _Tiles_TileGetIDFromPos($iX, $iY)
	For $i = 0 To UBound($aTiles) - 1 Step 1
		If $aTiles[$i][6] = $iX And $aTiles[$i][7] = $iY Then
			Return $i
		EndIf
	Next
	Return False
EndFunc   ;==>_Tiles_TileGetIDFromPos

Func _Tiles_TileCheckEmptySlot($iX, $iY)
	For $i = 0 To UBound($aTiles) - 1 Step 1
		If $aTiles[$i][6] = $iX And $aTiles[$i][7] = $iY Or ($aTiles[$i][6] = $iX + 1 And $aTiles[$i][7] = $iY And $aTiles[$i][6] = 0) Then
			Return False
		EndIf
	Next
	Return True
EndFunc   ;==>_Tiles_TileCheckEmptySlot

Func _Tiles_GetLastID()
	For $i = 0 To UBound($aTiles) - 1 Step 1
		If $aTiles[$i][0] = 0 Then
			Return $i
			ExitLoop
		EndIf
	Next
	Return False
EndFunc   ;==>_Tiles_GetLastID



Func _Tiles_Drag()
	Global $hTimer = TimerInit()
	AdlibRegister("_Tiles_CDrag", 10)
	Global $CInfo = GUIGetCursorInfo(@GUI_WinHandle)
	Global $aBeforeWinPos = WinGetPos(@GUI_WinHandle)
	Global $aMovePos = _Tiles_TileGetPos(@GUI_WinHandle)
	WinMove(@GUI_WinHandle, "", $aBeforeWinPos[0] + 4, $aBeforeWinPos[1] + 4, $aBeforeWinPos[2] - 8, $aBeforeWinPos[3] - 8)
	WinSetOnTop(@GUI_WinHandle, "", 1)
EndFunc   ;==>_Tiles_Drag

Func _Tiles_CDrag()
	Local $aWinPos = WinGetPos(@GUI_WinHandle)
	Local $MCInfo = GUIGetCursorInfo(@GUI_WinHandle)
	Local $aSplit = StringSplit(IniRead(@ScriptDir & "\settings.ini", "tiles", "1", "0|0"), "|")
	Local $iID = _Tiles_TileGetID(@GUI_WinHandle)
	If Not $MCInfo[2] Then
		Local $aTileCoord[2]
		AdlibUnRegister("_Tiles_CDrag")
		WinMove(@GUI_WinHandle, "", $aWinPos[0] - 4, $aWinPos[1] - 4, $aBeforeWinPos[2], $aBeforeWinPos[3])
		WinSetOnTop(@GUI_WinHandle, "", 0)
		#region Tile Snap
		If $aSplit[1] <> $aMovePos[0] Or $aSplit[2] <> $aMovePos[1] Then
			Local $aFirstWinPos = WinGetPos($aTiles[0][0])
			Local $iAddX = $iTilesZoneX - $aFirstWinPos[0]
			Local $iAddY = $iTilesZoneY - $aFirstWinPos[1]
			If Mod($aWinPos[0] + $iAddX, $iSpace + $iWidthUnit) < $iWidthUnit And Mod($aWinPos[1] + $iAddY, $iSpace + $iWidthUnit) < $iWidthUnit Then
				Local $iStartWidth = $aWinPos[0] + 12 + $iAddX
				Do
					$iStartWidth -= $iSpace + $iWidthUnit
				Until $iStartWidth < $iSpace
				Local $iStartHeight = $aWinPos[1] + 12 + $iAddY
				Do
					$iStartHeight -= $iSpace + $iWidthUnit
				Until $iStartHeight < $iSpace
				WinMove(@GUI_WinHandle, "", $aWinPos[0] + Abs($iStartWidth), $aWinPos[1] + Abs($iStartHeight))
			ElseIf Mod($aWinPos[0] + $iAddX, $iSpace + $iWidthUnit) > $iWidthUnit And Mod($aWinPos[1] + $iAddY, $iSpace + $iWidthUnit) < $iWidthUnit Then
				Local $iStartWidth = $aWinPos[0] + 12 + $iAddX
				Do
					$iStartWidth -= $iSpace + $iWidthUnit
				Until $iStartWidth < $iSpace
				Local $iStartHeight = $aWinPos[1] + 12 + $iAddY
				Do
					$iStartHeight -= $iSpace + $iWidthUnit
				Until $iStartHeight < $iSpace
				WinMove(@GUI_WinHandle, "", $aWinPos[0] - Abs($iStartWidth), $aWinPos[1] + Abs($iStartHeight))
			ElseIf Mod($aWinPos[0] + $iAddX, $iSpace + $iWidthUnit) < $iWidthUnit And Mod($aWinPos[1] + $iAddY, $iSpace + $iWidthUnit) > $iWidthUnit Then
				Local $iStartWidth = $aWinPos[0] + 12 + $iAddX
				Do
					$iStartWidth -= $iSpace + $iWidthUnit
				Until $iStartWidth < $iSpace
				Local $iStartHeight = $aWinPos[1] + 12 + $iAddY
				Do
					$iStartHeight -= $iSpace + $iWidthUnit
				Until $iStartHeight < $iSpace
				WinMove(@GUI_WinHandle, "", $aWinPos[0] + Abs($iStartWidth), $aWinPos[1] - Abs($iStartHeight))
			ElseIf Mod($aWinPos[0] + $iAddX, $iSpace + $iWidthUnit) > $iWidthUnit And Mod($aWinPos[1] + $iAddY, $iSpace + $iWidthUnit) > $iWidthUnit Then
				Local $iStartWidth = $aWinPos[0] + 12 + $iAddX
				Do
					$iStartWidth -= $iSpace + $iWidthUnit
				Until $iStartWidth < $iWidthUnit
				Local $iStartHeight = $aWinPos[1] + 12 + $iAddY
				Do
					$iStartHeight -= $iSpace + $iWidthUnit
				Until $iStartHeight < $iSpace
				WinMove(@GUI_WinHandle, "", $aWinPos[0] - Abs($iStartWidth), $aWinPos[1] - Abs($iStartHeight))
			ElseIf Mod($aWinPos[0] + $iAddX, $iSpace + $iWidthUnit) > $iWidthUnit And Mod($aWinPos[1] + $iAddY, $iSpace + $iWidthUnit) = $iWidthUnit Then
				Local $iStartWidth = $aWinPos[0] + 12 + $iAddX
				Do
					$iStartWidth -= $iSpace + $iWidthUnit
				Until $iStartWidth < $iSpace
				WinMove(@GUI_WinHandle, "", $aWinPos[0] - Abs($iStartWidth), $aWinPos[1])
			ElseIf Mod($aWinPos[0] + $iAddX, $iSpace + $iWidthUnit) = $iWidthUnit And Mod($aWinPos[1] + $iAddY, $iSpace + $iWidthUnit) > $iWidthUnit Then
				Local $iStartHeight = $aWinPos[1] + 12 + $iAddY
				Do
					$iStartHeight -= $iSpace + $iWidthUnit
				Until $iStartHeight < $iSpace
				WinMove(@GUI_WinHandle, "", $aWinPos[0], $aWinPos[1] - Abs($iStartHeight))
			ElseIf Mod($aWinPos[0] + $iAddX, $iSpace + $iWidthUnit) < $iWidthUnit And Mod($aWinPos[1] + $iAddY, $iSpace + $iWidthUnit) = $iWidthUnit Then
				Local $iStartWidth = $aWinPos[0] + 12 + $iAddX
				Do
					$iStartWidth -= $iSpace + $iWidthUnit
				Until $iStartWidth < $iSpace
				WinMove(@GUI_WinHandle, "", $aWinPos[0] + Abs($iStartWidth), $aWinPos[1])
			ElseIf Mod($aWinPos[0] + $iAddX, $iSpace + $iWidthUnit) = $iWidthUnit And Mod($aWinPos[1] + $iAddY, $iSpace + $iWidthUnit) < $iWidthUnit Then
				Local $iStartHeight = $aWinPos[1] + 12 + $iAddY
				Do
					$iStartHeight -= $iSpace + $iWidthUnit
				Until $iStartHeight < $iSpace
				WinMove(@GUI_WinHandle, "", $aWinPos[0], $aWinPos[1] + Abs($iStartHeight))
			EndIf
			Local $aNewPos = WinGetPos(@GUI_WinHandle)
			Local $aNewCoord = _Tiles_TileGetPos(@GUI_WinHandle)
			Local $bEmpty = _Tiles_TileCheckEmptySlot($aNewCoord[0], $aNewCoord[1])
			$aTiles[$iID][6] = $aNewCoord[0]
			$aTiles[$iID][7] = $aNewCoord[1]
			If $bEmpty = False Then
				WinMove(@GUI_WinHandle, "", $aBeforeWinPos[0], $aBeforeWinPos[1])
			EndIf
			If $aNewPos[1] + 3 >= @DesktopHeight - 20 Then WinMove(@GUI_WinHandle, "", $aNewPos[0], $aNewPos[1] - $iWidthUnit - $iSpace)
		EndIf
		#endregion Tile Snap
		#region Tile Click
		If TimerDiff($hTimer) < 100 Then
			If $aTiles[$iID][1] = "desktop" Then
				WinMinimizeAll()
			ElseIf $aTiles[$iID][1] = "lockscreen" Then
				If @OSArch = "X86" Then
					Run(@ScriptDir & "\MLLockscreen.exe")
				Else
					Run(@ScriptDir & "\MLLockscreen_x64.exe")
				EndIf
			ElseIf StringRight($aTiles[$iID][1], 3) = "exe" Then
				Run($aTiles[$iID][1])
			Else
				ShellExecute($aTiles[$iID][1])
			EndIf
		EndIf
		#endregion Tile Click
		Return
	EndIf
	$aMousePos = MouseGetPos()
	If Not IsArray($CInfo) Or Not IsArray($aMousePos) Then Return
	If $aSplit[1] <> $aMovePos[0] Or $aSplit[2] <> $aMovePos[1] And TimerDiff($hTimer) >= 100 Then
		WinMove(@GUI_WinHandle, "", $aMousePos[0] - $CInfo[0], $aMousePos[1] - $CInfo[1])
	EndIf
EndFunc   ;==>_Tiles_CDrag

Func _Tiles_RClick()
	Global $hRClickedTile = @GUI_WinHandle
	Local $aWinPos = WinGetPos(@GUI_WinHandle)
	WinMove(@GUI_WinHandle, "", $aWinPos[0] + 4, $aWinPos[1] + 4, $aWinPos[2] - 8, $aWinPos[3] - 8)
	Sleep(25)
	WinMove(@GUI_WinHandle, "", $aWinPos[0], $aWinPos[1], $aWinPos[2], $aWinPos[3])
	Global $hContext = GUICreate("Tile context menu", @DesktopWidth, 64, 0, @DesktopHeight - 64, $WS_POPUP, Default, $hParent)
	WinSetOnTop($hContext, "", 1)
	Global $hContextGraphics = _GDIPlus_GraphicsCreateFromHWND($hContext)
	Local $hDelete = GUICtrlCreateLabel("", @DesktopWidth / 2 - 96, 8, 48, 48)
	GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
	GUICtrlSetOnEvent(-1, "_TileDelete")
	Local $hDimension = GUICtrlCreateLabel("", @DesktopWidth / 2 - 32, 8, 48, 48)
	GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
	GUICtrlSetOnEvent(-1, "_TileChangeDim")
	Local $hRename = GUICtrlCreateLabel("", @DesktopWidth / 2 + 32, 8, 48, 48)
	GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
	GUICtrlSetOnEvent(-1, "_TileRename")
	Local $hTilePic = GUICtrlCreateLabel("", @DesktopWidth / 2 + 96, 8, 48, 48)
	GUICtrlSetOnEvent(-1, "_TileChangeBG")
	GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
	GUISetBkColor(0x000000)
	GUISetState(@SW_SHOW)
	_GUI_MoveControl($hContext, 4)
	AdlibRegister("_ContextDeleteOnFocusLose", 10)
EndFunc   ;==>_Tiles_RClick

Func _ContextDeleteOnFocusLose()
	If IsHWnd($hContext) And Not WinActive("Tile context menu") Then
		AdlibUnRegister("_ContextDeleteOnFocusLose")
		GUIDelete($hContext)
	EndIf
EndFunc   ;==>_ContextDeleteOnFocusLose

Func _TileDelete()
	GUIDelete($hRClickedTile)
	Local $sRead = _Tiles_TileGetID($hRClickedTile) + 1
	For $i = 0 To UBound($aTiles, 2) - 1 Step 1
		$aTiles[$sRead - 1][$i] = 0
	Next
	If IsHWnd($hContext) Then
		AdlibUnRegister("_ContextDeleteOnFocusLose")
		GUIDelete($hContext)
	EndIf
	IniDelete(@ScriptDir & "\settings.ini", "tiles", $sRead)
EndFunc   ;==>_TileDelete

Func _TileRename()
	Local $bEnd = False
	Local $sNewName = InputBox($aLang[7], $aLang[8])
	If Not @error Then
		Local $iID = _Tiles_TileGetID($hRClickedTile)
		Local $aPos = _Tiles_TileGetPos($hRClickedTile)
		$aTiles[$iID][3] = $sNewName
		GUICtrlSetData($aTiles[$iID][8], $sNewName)
	EndIf
EndFunc   ;==>_TileRename

Func _TileChangeBG()
	Global $hBGInput = _MetroUI_CreatePopupInput($hMainGUI, 0, 0, @DesktopWidth, 36, 0x000000, 0xa0a0a0, $aLang[9], True, $aLang[11] & @CRLF & $aLang[12] & @CRLF & $aLang[13], $aLang[10], 1)
	WinSetOnTop($hBGInput[0], "", 1)
	AdlibRegister("_TileBGCloseOnFocusLose", 10)
	HotKeySet("{ENTER}", "_TileChangeBGConfirm")
EndFunc   ;==>_TileChangeBG

Func _TileChangeBGConfirm()
	Local $bEnd = False
	Local $sNewBG = StringReplace(GUICtrlRead($hBGInput[1]), "#", "0x")
	If $sNewBG = "0x000001" Then $sNewBG = "0x000000"
	Local $aSections = IniReadSection(@ScriptDir & "\settings.ini", "tiles")
	For $i = 1 To $aSections[0][0] Step 1
		For $i2 = 0 To UBound($aTiles, 1) - 1 Step 1
			If $hRClickedTile = $aTiles[$i2][0] Then
				If $i2 = $aSections[$i][0] - 1 Then
					Local $sRead = $aSections[$i][0]
					Local $aPos[2] = [$aTiles[$i2][6], $aTiles[$i2][7]]
					Local $bEnd = True
					ExitLoop
				EndIf
			EndIf
		Next
		If $bEnd = True Then ExitLoop
	Next
	Local $iID = _Tiles_TileGetID($hRClickedTile)
	$aTiles[$iID][2] = $sNewBG
	If StringLeft(Binary($sNewBG), 2) = "0x" And StringLen($sNewBG) = 8 Then
		If $aTiles[$iID][5] <> 0 Then GUICtrlDelete($aTiles[$iID][5])
		GUISetBkColor($sNewBG, $aTiles[$iID][0])
	ElseIf FileExists($sNewBG) Then
		MsgBox(64, $aLang[46], $aLang[47])
	EndIf
	AdlibUnRegister("_TileBGCloseOnFocusLose")
	HotKeySet("{ENTER}")
	GUIDelete($hBGInput[0])
EndFunc   ;==>_TileChangeBGConfirm

Func _TileBGCloseOnFocusLose()
	Local $aMousePos = MouseGetPos()
	If _IsPressed("11") And _IsPressed("01") And $aMousePos[0] >= @DesktopWidth / 8 And $aMousePos[0] <= @DesktopWidth / 4 * 3 And $aMousePos[1] >= 0 And $aMousePos[1] <= 36 Then
		Local $sOpen = FileOpenDialog($aLang[14], @DesktopDir, $aLang[15] & " (*.jpg;*.bmp;*.gif;*.png)", 1 + 2)
		If Not @error Then
			GUICtrlSetData($hBGInput[1], $sOpen)
		EndIf
	ElseIf _IsPressed("12") And _IsPressed("01") And $aMousePos[0] >= @DesktopWidth / 8 And $aMousePos[0] <= @DesktopWidth / 4 * 3 And $aMousePos[1] >= 0 And $aMousePos[1] <= 36 Then
		Local $sColor = _ChooseColor(2, Default, Default, $hBGInput[0])
		If $sColor <> -1 Then
			GUICtrlSetData($hBGInput[1], StringReplace($sColor, "0x", "#"))
		EndIf
	EndIf
	If IsDeclared("hBGInput") And Not WinActive($hBGInput[0]) Then
		AdlibUnRegister("_TileBGCloseOnFocusLose")
		HotKeySet("{ENTER}")
		GUIDelete($hBGInput[0])
	EndIf
EndFunc   ;==>_TileBGCloseOnFocusLose

Func _TileChangeDim()
	Local $aPos = _Tiles_TileGetPos($hRClickedTile)
	Local $iID = _Tiles_TileGetID($hRClickedTile)
	If $aTiles[$iID][4] = 2 Then
		Local $iNewWidth = 1
	Else
		Local $iNewWidth = 2
	EndIf
	Local $aWinPos = WinGetPos($aTiles[$iID][0])
	$aTiles[$iID][4] = $iNewWidth
	WinMove($aTiles[$iID][0], "", $aWinPos[0], $aWinPos[1], $iWidthUnit * $iNewWidth + $iSpace * ($iNewWidth - 1), $iWidthUnit)
	For $i = $aPos[0] + 1 To UBound($aTiles) - 1 Step 1
		Local $iID = _Tiles_TileGetIDFromPos($i, $aPos[1])
		If $iID <> False Then
			Local $aWinPos = WinGetPos($aTiles[$iID][0])
			If $iNewWidth = 2 Then
				WinMove($aTiles[$iID][0], "", $aWinPos[0] + $iSpace + $iWidthUnit, $aWinPos[1])
			Else
				WinMove($aTiles[$iID][0], "", $aWinPos[0] - $iSpace - $iWidthUnit, $aWinPos[1])
			EndIf
		EndIf
	Next
EndFunc   ;==>_TileChangeDim

Func _GDIPlus_BitmapCreateDIBFromBitmap($hBitmap)
	Local $tBIHDR, $Ret, $tData, $pBits, $hResult = 0
	$Ret = DllCall($ghGDIPDll, 'uint', 'GdipGetImageDimension', 'ptr', $hBitmap, 'float*', 0, 'float*', 0)
	If (@error) Or ($Ret[0]) Then
		Return 0
	EndIf
	$tData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $Ret[2], $Ret[3], $GDIP_ILMREAD, $GDIP_PXF32ARGB)
	$pBits = DllStructGetData($tData, 'Scan0')
	If Not $pBits Then
		Return 0
	EndIf
	$tBIHDR = DllStructCreate('dword;long;long;ushort;ushort;dword;dword;long;long;dword;dword')
	DllStructSetData($tBIHDR, 1, DllStructGetSize($tBIHDR))
	DllStructSetData($tBIHDR, 2, $Ret[2])
	DllStructSetData($tBIHDR, 3, $Ret[3])
	DllStructSetData($tBIHDR, 4, 1)
	DllStructSetData($tBIHDR, 5, 32)
	DllStructSetData($tBIHDR, 6, 0)
	$hResult = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBIHDR), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'dword', 0)
	If (Not @error) And ($hResult[0]) Then
		DllCall('gdi32.dll', 'dword', 'SetBitmapBits', 'ptr', $hResult[0], 'dword', $Ret[2] * $Ret[3] * 4, 'ptr', DllStructGetData($tData, 'Scan0'))
		$hResult = $hResult[0]
	Else
		$hResult = 0
	EndIf
	_GDIPlus_BitmapUnlockBits($hBitmap, $tData)
	Return $hResult
EndFunc   ;==>_GDIPlus_BitmapCreateDIBFromBitmap

Func _GDIPlus_ScaleImage($sFile, $iW, $iH, $iInterpolationMode = 7) ;coded by UEZ 2012
	If Not FileExists($sFile) Then Return SetError(1, 0, 0)
	Local $hImage = _GDIPlus_ImageLoadFromFile($sFile)
	If @error Then Return SetError(2, 0, 0)
	Local $hBitmap = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iW, "int", $iH, "int", 0, "int", 0x0026200A, "ptr", 0, "int*", 0)
	If @error Then Return SetError(3, 0, 0)
	$hBitmap = $hBitmap[6]
	Local $hBmpCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap)
	DllCall($ghGDIPDll, "uint", "GdipSetInterpolationMode", "handle", $hBmpCtxt, "int", $iInterpolationMode)
	_GDIPlus_GraphicsDrawImageRect($hBmpCtxt, $hImage, 0, 0, $iW, $iH)
	_GDIPlus_ImageDispose($hImage)
	_GDIPlus_GraphicsDispose($hBmpCtxt)
	Return $hBitmap
EndFunc   ;==>_GDIPlus_ScaleImage
